package jenkins.plugins.logstash.persistence;

import com.cloudbees.syslog.MessageFormat;
import com.cloudbees.syslog.sender.UdpSyslogMessageSender;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import net.sf.json.JSONObject;
import org.junit.Before;
import org.junit.Test;

import static org.awaitility.Awaitility.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class SyslogDaoTestIT{
  SyslogDao dao;
  String data = "{ 'junit': 'SyslogDaoTest' }";
  String host = "localhost";
  String appname = "jenkins:";
  String logfile = "target/logs/syslog-test.log";
  String logmessage = "";
  String logcontent = "";
  int port = 514;
  int logstashTimeout = 15;
  UdpSyslogMessageSender udpSyslogMessageSender = new UdpSyslogMessageSender();

  @Before
  public void before() throws Exception {
    dao = createDao(host, port, null, null, null);
  }

  // Send a real Syslog message to Logstash.
  @Test
  public void syslogSendRFC3164UDP() throws Exception {
    // Clean up the the logstash log file
    try (PrintWriter writer = new PrintWriter(logfile)) {
    } catch (FileNotFoundException e) {
      fail("Unable to clean up the logstash log file: " + e.getMessage());
    }

    // Send the syslog message
    dao.setMessageFormat(MessageFormat.RFC_3164);
    dao.push(data);

    // Await for logstash to process the message
    try {
      await().atMost(logstashTimeout, TimeUnit.SECONDS).until(logfileIsNotEmpty());
    }
    catch (Exception e) {
      fail("Unable to find any logstash generated data within the logfile " + logfile +  ": " + e.getMessage());
    }

    // Parse the logstash generated logfile
    try {
      JSONObject logjson = JSONObject.fromObject(logcontent);
      logmessage = logjson.get("message").toString();
    }
    catch (Exception e) {
      fail("Unable to parse the logstash generated logfile content: " + e.getMessage());
    }

    assertEquals(" @cee: " + data, logmessage);

  }

  private Callable<Boolean> logfileIsNotEmpty() {
    return new Callable<Boolean>() {
      @Override
    public Boolean call() throws Exception {
        // Check the content of logfile generated by logstash
        logcontent = new String(Files.readAllBytes(Paths.get(logfile)));
        // The condition that must be fulfilled
        return logcontent.length() > 0;
      }
    };
  }

  SyslogDao createDao(String host, int port, String key, String username, String password) {
    return new SyslogDao(udpSyslogMessageSender, host, port);
  }

}
